﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Centny.PdfReader.util
{
    public class PdfMatrix
    {
        public static double[] UnitMartixArray ={ 1, 0, 0,
                                                 0, 1, 0,
                                                 0, 0, 1 };
        private double[] vals = new double[9];

        public PdfMatrix()
        {
            this.Reset();
        }
        public void Reset()
        {
            Array.Copy(UnitMartixArray, vals, 9);
        }
        public PdfMatrix Mulp(PdfMatrix m)
        {
            PdfMatrix nm = new PdfMatrix();
            this.Multiply(m, nm);
            return nm;
        }
        public void Multiply(PdfMatrix m)
        {
            this.Multiply(m, this);
        }
        public void Multiply(PdfMatrix right, PdfMatrix res)
        {
            double[] lval = this.vals;
            double[] rval = right.vals;
            double[] resval = res.vals;
            if (this == res)
            {
                lval = this.CopyArray();
            }
            if (right == res)
            {
                rval = right.CopyArray();
            }
            resval[0] = lval[0] * rval[0] + lval[1] * rval[3] + lval[2] * rval[6];
            resval[1] = lval[0] * rval[1] + lval[1] * rval[4] + lval[2] * rval[7];
            resval[2] = lval[0] * rval[2] + lval[1] * rval[5] + lval[2] * rval[8];
            resval[3] = lval[3] * rval[0] + lval[4] * rval[3] + lval[5] * rval[6];
            resval[4] = lval[3] * rval[1] + lval[4] * rval[4] + lval[5] * rval[7];
            resval[5] = lval[3] * rval[2] + lval[4] * rval[5] + lval[5] * rval[8];
            resval[6] = lval[6] * rval[0] + lval[7] * rval[3] + lval[8] * rval[6];
            resval[7] = lval[6] * rval[1] + lval[7] * rval[4] + lval[8] * rval[7];
            resval[8] = lval[6] * rval[2] + lval[7] * rval[5] + lval[8] * rval[8];
        }
        public double[] CopyArray()
        {
            double[] nary = new double[vals.Length];
            Array.Copy(this.vals, nary, this.vals.Length);
            return nary;
        }
        public double Get(int row, int col)
        {
            return this.vals[row * 3 + col];
        }
        public void Set(int row, int col, double val)
        {
            this.vals[row * 3 + col] = val;
        }
        public PdfMatrix Clone()
        {
            PdfMatrix m = new PdfMatrix();
            Array.Copy(this.vals, m.vals, this.vals.Length);
            return m;
        }
        public Row this[int row]
        {
            get
            {
                return new Row(row, this);
            }
        }
        public class Row
        {
            public int row;
            public PdfMatrix m;
            public Row(int row, PdfMatrix m)
            {
                this.row = row;
                this.m = m;
            }
            public double this[int col]
            {
                get
                {
                    return this.m.Get(row, col);
                }
                set
                {
                    this.m.Set(row, col, value);
                }
            }
        }
    }
}
